package cn.lbd.kill.server.service;

import cn.lbd.kill.model.dto.KillSuccessUserInfo;
import cn.lbd.kill.model.entity.ItemKillSuccess;
import cn.lbd.kill.model.mapper.ItemKillMapper;
import cn.lbd.kill.model.mapper.ItemKillSuccessMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.AbstractJavaTypeMapper;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

@Service
public class RabbitSenderService {
    private static final Logger logger = LoggerFactory.getLogger(RabbitSenderService.class);
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private Environment environment;
    @Autowired(required = false)
    private ItemKillSuccessMapper itemKillSuccessMapper;

    /**
     * 秒杀成功异步发送邮件通知消息
     */
    public void sendKillSuccessEmailMsg(String orderNo) {
        logger.info("秒杀成功异步发送邮件通知消息-准备发送消息：{}", orderNo);
        try {
            if (!StringUtils.isEmpty(orderNo)) {
                KillSuccessUserInfo killSuccessUserInfo = itemKillSuccessMapper.selectByCode(orderNo);
                if (killSuccessUserInfo != null) {
                    //将JDK序列化规则换成json序列化规则，当前往MQ中发送对象数据
                    rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
                    //这二者的set()可以不在这里指定，可以直接通过传参的方式，将交换机和路由键传到1convertAndSend方法中
                    rabbitTemplate.setExchange(environment.getProperty("mq.kill.item.success.email.exchange"));
                    rabbitTemplate.setRoutingKey(environment.getProperty("mq.kill.item.success.email.routing.key"));
                    //消息构建器，消息体传字节数组
                    /*Message 。 = MessageBuilder.withBody(orderNo.getBytes("UTF-8")).build();
                    rabbitTemplate.convertAndSend(message);*/
                    //把秒杀成功的用户信息发送到消息队列
                    rabbitTemplate.convertAndSend(killSuccessUserInfo, new MessagePostProcessor() {
                        @Override
                        public Message postProcessMessage(Message message) throws AmqpException {
                            // 获得消息属性
                            MessageProperties messageProperties = message.getMessageProperties();
                            // 保证消息可靠性，进行持久化
                            messageProperties.setDeliveryMode(MessageDeliveryMode.PERSISTENT);
                            // 设置消息头，指定确切类型，消费者那里直接用对象接收，也就是监听器方法的入参直接用KillSuccessUserInfo
                            messageProperties.setHeader(AbstractJavaTypeMapper.DEFAULT_CONTENT_CLASSID_FIELD_NAME, KillSuccessUserInfo.class);
                            return message;
                        }
                    });
                }
            }
        } catch (Exception e) {
            logger.error("秒杀成功异步发送邮件通知消息-发生异常，消息为：{}", orderNo, e.fillInStackTrace());
        }
    }

    /**
     * 秒杀成功后生成抢购订单-发送信息入死信队列，等待着一定时间失效超时未支付的订单
     * 死信队列，延迟处理消息
     *
     * @param orderNo
     */
    public void sendExpireKillSuccessMsg(String orderNo) {
        try {
            if (!StringUtils.isEmpty(orderNo)) {
                KillSuccessUserInfo killSuccessUserInfo = itemKillSuccessMapper.selectByCode(orderNo);
                if (killSuccessUserInfo != null) {
                    rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
                    rabbitTemplate.setExchange(environment.getProperty("mq.kill.item.success.kill.dead.prod.exchange"));
                    rabbitTemplate.setRoutingKey(environment.getProperty("mq.kill.item.success.kill.dead.prod.routing.key"));
                    rabbitTemplate.convertAndSend(killSuccessUserInfo, new MessagePostProcessor() {
                        @Override
                        public Message postProcessMessage(Message message) throws AmqpException {
                            MessageProperties messageProperties = message.getMessageProperties();
                            messageProperties.setDeliveryMode(MessageDeliveryMode.PERSISTENT);
                            messageProperties.setHeader(AbstractJavaTypeMapper.DEFAULT_CONTENT_CLASSID_FIELD_NAME,KillSuccessUserInfo.class);
                            //设置订单超时时间 TTL
                            messageProperties.setExpiration(environment.getProperty("mq.kill.item.success.kill.expire"));
                            return message;
                        }
                    });
                }
            }
        } catch (Exception e) {
            logger.error("秒杀成功后生成抢购订单-发送信息入死信队列，等待着一定时间失效超时未支付的订单-发生异常，消息为：{}", orderNo, e.fillInStackTrace());
        }
    }
}
